#include "student.h"

//全局变量定义（对应头文件的extern声明）
Student *g_student_list = NULL;
pthread_mutex_t g_list_mutex = PTHREAD_MUTEX_INITIALIZER;

//更新链表序号
void update_num() {
    int num = 1;
    Student *temp = g_student_list;
    while (temp != NULL) {
        temp->num = num++;
        temp = temp->next;
    }
}


//初始化链表
void init_student_list() {
    g_student_list = NULL;  // 空链表
}



//创建新节点
Student* create_student(int num, const char *id, const char *name, const char *gender, int age) {
    Student *new_node = (Student*)malloc(sizeof(Student));
    if (new_node == NULL) {
        perror("内存分配失败");
        return NULL;
    }
    // 赋值成员变量
    new_node->num = num;
    strcpy(new_node->id, id);
    strcpy(new_node->name, name);
    strcpy(new_node->gender, gender);
    new_node->age = age;
    new_node->next = NULL;
    return new_node;
}

//添加学生信息（按学号升序）
int add_student(int num, const char *id, const char *name, const char *gender, int age) {
    pthread_mutex_lock(&g_list_mutex);  // 加锁保护共享链表

    // 1. 检查学号是否已存在
    Student *temp = g_student_list;
    while (temp != NULL) {
        if (strcmp(temp->id, id) == 0) {
            pthread_mutex_unlock(&g_list_mutex);  // 解锁
            return -1;  // 学号已存在
        }
        temp = temp->next;
    }

    // 2. 创建新节点
    Student *new_node = create_student(0, id, name, gender, age);   // 序号暂设为0,后面会重新编号
    if (new_node == NULL) {
        pthread_mutex_unlock(&g_list_mutex);
        return -1;
    }

    // 3. 按学号升序插入（strcmp比较字符串大小）
    // 情况1：链表为空，直接作为头节点
    if (g_student_list == NULL) {
        g_student_list = new_node;
        update_num();
        pthread_mutex_unlock(&g_list_mutex);
        return 0;
    }

    // 情况2：插入到链表头部（新学号 < 头节点学号）
    if (strcmp(new_node->id, g_student_list->id) < 0) {
        new_node->next = g_student_list;
        g_student_list = new_node;
        update_num();
        pthread_mutex_unlock(&g_list_mutex);
        return 0;
    }

    // 情况3：插入到链表中间或尾部
    Student *prev = g_student_list;
    temp = g_student_list->next;
    while (temp != NULL) {
        if (strcmp(new_node->id, temp->id) < 0) {  // 找到插入位置
            prev->next = new_node;
            new_node->next = temp;
            update_num();
            pthread_mutex_unlock(&g_list_mutex);
            return 0;
        }
        prev = temp;
        temp = temp->next;
    }

    // 情况4：插入到尾部（新学号最大）
    prev->next = new_node;
    update_num();
    // 4.  解锁
    pthread_mutex_unlock(&g_list_mutex);
    return 0;
}

//删除学生信息（按学号）
int delete_student(const char *id) {
    pthread_mutex_lock(&g_list_mutex);

    Student *temp = g_student_list;
    Student *prev = NULL;

    // 查找要删除的节点
    while (temp != NULL) {
        if (strcmp(temp->id, id) == 0) {  // 找到节点
            // 情况1：删除头节点
            if (prev == NULL) {
                g_student_list = temp->next;
            } else {  // 情况2：删除中间或尾部节点
                prev->next = temp->next;
            }
            free(temp);  // 释放内存
            update_num();
            pthread_mutex_unlock(&g_list_mutex);
            return 0;
        }
        prev = temp;
        temp = temp->next;
    }
    // 未找到节点
    pthread_mutex_unlock(&g_list_mutex);
    return -1;
}

//修改学生信息（按旧学号）
int update_student(const char *old_id, const char *new_id, const char *new_name, const char *new_gender, int new_age) {
    pthread_mutex_lock(&g_list_mutex);

    //1、检查链表是否为空
    if(g_student_list == NULL) {
        printf("错误：请先添加学生信息！\n");
        pthread_mutex_unlock(&g_list_mutex);
        return -1;
    }

    Student *temp = g_student_list;
    Student *prev = NULL;

    //2、查找要修改的学生
    while (temp != NULL) {
        //找到旧学号节点
        if (strcmp(temp->id, old_id) == 0) { 

            //如果学号有修改
            if (strcmp(new_id, old_id) != 0) {  

                //检查新学号是否已存在

                //情况1：新学号重复
                Student *check = g_student_list;
                while (check != NULL) {
                    if (strcmp(check->id, new_id) == 0 && check != temp) {
                        printf("错误：新学号已存在！\n");
                        pthread_mutex_unlock(&g_list_mutex);
                        return -1;  // 新学号已存在
                    }
                    check = check->next;
                }

                //情况2：新学号不重复
                //移除当前节点
                if (prev == NULL) {
                    g_student_list = temp->next;
                } else {
                    prev->next = temp->next;
                }

                //更新节点信息
                strcpy(temp->id, new_id);
                strcpy(temp->name, new_name);
                strcpy(temp->gender, new_gender);
                temp->age = new_age;
                temp->next = NULL;

                //重新插入节点（按新学号升序）
                Student *curr = g_student_list;
                Student *insert_prev = NULL;
                
                while (curr != NULL && strcmp(new_id, curr->id) > 0) {
                    insert_prev = curr;
                    curr = curr->next;
                }
                
                if (insert_prev == NULL) {
                    // 插入到链表头部
                    temp->next = g_student_list;
                    g_student_list = temp;
                } else {
                    // 插入到中间或尾部
                    temp->next = insert_prev->next;
                    insert_prev->next = temp;
                }
            } else {

                // 学号未修改，直接更新其他信息
                strcpy(temp->name, new_name);
                strcpy(temp->gender, new_gender);
                temp->age = new_age;
            }
            update_num();
            pthread_mutex_unlock(&g_list_mutex);
            return 0;
        }
        prev = temp;
        temp = temp->next;
    }
    // 未找到旧学号
    printf("错误：该学号不存在！\n");
    pthread_mutex_unlock(&g_list_mutex);
    return -1;
}

//查找学生信息（模糊匹配学号/姓名），结果存入result链表
int search_student(const char *keyword, Student **result) {
    pthread_mutex_lock(&g_list_mutex);

    *result = NULL;  // 结果链表初始化
    Student *last = NULL;  // 指向结果链表的尾部，方便插入
    int count = 0;

    Student *temp = g_student_list;
    while (temp != NULL) {
        // 模糊匹配：学号包含keyword 或 姓名包含keyword
        if (strstr(temp->id, keyword) != NULL || strstr(temp->name, keyword) != NULL) {
            // 创建新节点存入结果链表（避免修改原链表）
            Student *new_node = create_student(temp->num, temp->id, temp->name, temp->gender, temp->age);
            if (new_node == NULL) {
                temp = temp->next;
                continue;
            }
            // 插入结果链表尾部
            if (*result == NULL) {
                *result = new_node;
                last = new_node;
            } else {
                last->next = new_node;
                last = new_node;
            }
            count++;
        }
        temp = temp->next;
    }

    pthread_mutex_unlock(&g_list_mutex);
    return count;
}

//获取链表长度（用于生成序号num）
int get_list_length() {
    pthread_mutex_lock(&g_list_mutex);

    int length = 0;
    Student *temp = g_student_list;
    while (temp != NULL) {
        length++;
        temp = temp->next;
    }

    pthread_mutex_unlock(&g_list_mutex);
    return length;
}

//销毁链表
void destroy_student_list() {
    pthread_mutex_lock(&g_list_mutex);

    Student *current = g_student_list;
    while (current != NULL) {
        Student *next = current->next;
        free(current);  // 释放当前节点
        current = next;
    }
    g_student_list = NULL;  // 链表为空

    pthread_mutex_unlock(&g_list_mutex);
}